<template>
  <ElDialog
    :title="dialogTitle"
    :model-value="visible"
    @update:model-value="handleCancel"
    width="800px"
    align-center
    class="menu-dialog"
    @closed="handleClosed"
  >
    <ElForm ref="formRef" :model="form" :rules="rules" label-width="85px">
      <ElFormItem label="菜单类型">
        <ElRadioGroup v-model="menuType" :disabled="disableMenuType">
          <ElRadioButton value="menu" label="menu">菜单</ElRadioButton>
          <ElRadioButton value="button" label="button">按钮</ElRadioButton>
        </ElRadioGroup>
      </ElFormItem>

      <!-- 菜单表单 -->
      <template v-if="menuType === 'menu'">
        <ElRow :gutter="20">
          <ElCol :span="12">
            <ElFormItem label="菜单名称" prop="title">
              <ElInput v-model="form.title" placeholder="菜单名称:菜单管理" />
            </ElFormItem>
          </ElCol>
          <ElCol :span="12">
            <ElFormItem label="路由地址" prop="path">
              <ElInput v-model="form.path" placeholder="路由地址：/menu" />
            </ElFormItem>
          </ElCol>
        </ElRow>
        <div class="text-xs text-red-500 mb-2"
          >菜单多级嵌套下面还有菜单的情况下组件路径为空路由地址不带/权限标识与路由一样</div
        >
        <ElRow :gutter="20" v-if="props.editData?.types !== 1">
          <ElCol :span="12">
            <ElFormItem label="权限标识" prop="name">
              <ElInput v-model="form.name" placeholder="权限标识:menu.list" />
            </ElFormItem>
          </ElCol>
          <ElCol :span="12">
            <ElFormItem label="组件路径" prop="component">
              <ElInput v-model="form.component" placeholder="组件路径:/system/menu" />
            </ElFormItem>
          </ElCol>
        </ElRow>

        <ElRow :gutter="20">
          <ElCol :span="12">
            <ElFormItem label="菜单图标" prop="icon">
              <ElInput
                v-model="form.icon"
                placeholder="请输入或选择图标名称"
                style="width: 300px"
                clearable
              >
                <template #prefix>
                  <IconifyIcon v-if="form.icon" :icon="form.icon" width="20" height="20" />
                </template>
                <template #append>
                  <ElButton @click.stop="iconPickerVisible = true">选择图标</ElButton>
                </template>
              </ElInput>
              <IconPicker v-model="iconPickerVisible" @select="handleIconSelect" title="选择图标" />
            </ElFormItem>
          </ElCol>
          <ElCol :span="12">
            <ElFormItem label="菜单排序" prop="sort">
              <ElInputNumber
                v-model="form.sort"
                style="width: 100%"
                :min="0"
                controls-position="right"
              />
            </ElFormItem>
          </ElCol>
        </ElRow>

        <ElRow :gutter="20">
          <ElCol :span="6">
            <ElFormItem label="是否启用" prop="status">
              <ElSwitch v-model="form.status" :active-value="1" :inactive-value="0" />
            </ElFormItem>
          </ElCol>
          <ElCol :span="18">
            <ElFormItem label="上级菜单" prop="pid">
              <ElSelect v-model="form.pid" placeholder="请选择上级菜单" filterable clearable>
                <ElOption :value="0" label="顶级菜单" />
                <ElOption
                  v-for="item in flatMenuList"
                  :key="item.id"
                  :value="item.id"
                  :label="item.meta?.title || item.title"
                  :disabled="item.id === form.id"
                />
              </ElSelect>
            </ElFormItem>
          </ElCol>
        </ElRow>
      </template>

      <!-- 权限表单 -->
      <template v-if="menuType === 'button'">
        <ElRow :gutter="20">
          <ElCol :span="9">
            <ElFormItem label="权限名称" prop="title">
              <ElInput v-model="form.title" placeholder="权限名称:添加" />
            </ElFormItem>
          </ElCol>
          <ElCol :span="9">
            <ElFormItem label="权限标识" prop="name">
              <ElInput v-model="form.name" placeholder="权限标识:menu.add" />
            </ElFormItem>
          </ElCol>
          <ElCol :span="6">
            <ElFormItem label="权限排序" prop="sort">
              <ElInputNumber
                v-model="form.sort"
                style="width: 100%"
                :min="0"
                controls-position="right"
              />
            </ElFormItem>
          </ElCol>
        </ElRow>
      </template>
    </ElForm>

    <template #footer>
      <span class="dialog-footer">
        <ElButton @click="handleCancel">取 消</ElButton>
        <ElButton type="primary" @click="handleSubmit">确 定</ElButton>
      </span>
    </template>
  </ElDialog>
</template>

<script setup lang="ts">
  import type { FormInstance, FormRules } from 'element-plus'
  import { Icon as IconifyIcon } from '@iconify/vue'
  import IconPicker from '@/components/iconpicker/IconPicker.vue'
  import type { AppRouteRecord } from '@/types/router'
  import { addMenuApi, editMenuApi } from '@/api/system-manage'
  const iconPickerVisible = ref(false)
  function handleIconSelect(icon: string) {
    form.icon = icon
    iconPickerVisible.value = false
  }
  interface Props {
    visible: boolean
    editData?: AppRouteRecord | any
    type?: 'menu' | 'button'
    lockType?: boolean
    menuList?: AppRouteRecord[]
  }
  const flatMenuList = computed(() => {
    const result: any[] = []
    const loop = (list: any[], level = 0) => {
      list.forEach((item) => {
        result.push({
          ...item,
          level,
          label: `${'—'.repeat(level)}${item.meta?.title || item.title}`
        })
        if (item.children && item.children.length) {
          loop(item.children, level + 1)
        }
      })
    }
    if (props.menuList) loop(props.menuList)
    return result
  })
  interface Emits {
    (e: 'update:visible', value: boolean): void
    (e: 'submit', data: any): void
  }

  const props = withDefaults(defineProps<Props>(), {
    visible: false,
    type: 'menu',
    lockType: false
  })

  const emit = defineEmits<Emits>()

  const formRef = ref<FormInstance>()
  const menuType = ref<'menu' | 'button'>('menu')
  const isEdit = ref(false)

  const form = reactive<any>({
    id: 0,
    pid: 0,
    name: '',
    path: '',
    title: '',
    component: '',
    icon: '',
    status: 1,
    sort: 1,
    is_menu: props.type === 'button' ? 0 : 1
  })

  const rules = reactive<FormRules>({
    title: [
      { required: true, message: '请输入菜单名称', trigger: 'blur' },
      { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
    ],
    path: [{ required: true, message: '请输入路由地址', trigger: 'blur' }],
    name: [{ required: true, message: '输入权限标识', trigger: 'blur' }],
    component: [{ required: false, message: '请输入组件路径', trigger: 'blur' }],
    icon: [{ required: false, message: '请选择菜单图标', trigger: 'blur' }],
    sort: [{ required: true, message: '请输入菜单排序', trigger: 'blur' }],
    authMark: [{ required: false, message: '请输入权限标识', trigger: 'blur' }]
  })

  const dialogTitle = computed(() => {
    const type = menuType.value === 'menu' ? '菜单' : '按钮'
    return isEdit.value ? `编辑${type}` : `新建${type}`
  })

  /**
   * 是否禁用菜单类型切换
   */
  const disableMenuType = computed(() => {
    if (isEdit.value) return true
    if (!isEdit.value && menuType.value === 'menu' && props.lockType) return true
    return false
  })

  /**
   * 重置表单数据
   */
  const resetForm = (): void => {
    formRef.value?.resetFields()
    Object.assign(form, {
      id: 0,
      name: '',
      path: '',
      title: '',
      component: '',
      icon: '',
      sort: 1,
      status: 1,
      pid: 0
    })
  }

  /**
   * 加载表单数据（编辑模式）
   */
  const loadFormData = (): void => {
    if (!props.editData) return

    isEdit.value = true

    if (menuType.value === 'menu') {
      const row = props.editData
      form.pid = row.p_id || 0
      form.id = row.id || 0
      form.name = row.name || ''
      form.path = row.path || ''
      form.component = row.component || ''
      form.icon = row.meta?.icon || ''
      form.title = row.meta?.title || ''
      form.sort = row.meta?.sort || 1
      form.status =
        row.meta?.status === true
          ? 1
          : row.meta?.status === false
            ? 0
            : Number(row.meta?.status ?? 1)
    } else {
      const row = props.editData
      form.id = row.id || 0
      form.pid = row.p_id || 0
      form.title = row.title || ''
      form.name = row.authMark || ''
      form.sort = row.meta?.sort || 1
      form.status =
        row.meta?.status === true
          ? 1
          : row.meta?.status === false
            ? 0
            : Number(row.meta?.status ?? 1)
    }
  }

  /**
   * 提交表单
   */
  const handleSubmit = async (): Promise<void> => {
    if (!formRef.value) return
    await formRef.value.validate(async (valid) => {
      if (valid) {
        if (props.editData.add === 1) {
          const edittype = props.editData.meta?.type ?? props.editData.type
          if (edittype === 1) {
            delete form.is_menu
            form.permission = form.name
            form.type = 2
            delete form.name
          } else if (edittype === 2) {
            form.type = 3
            form.permission = form.name
            delete form.name
            delete form.is_menu
            delete form.component
            delete form.icon
            delete form.path
          } else {
            delete form.is_menu
            delete form.name
            form.type = 1
            form.permission = form.path
            form.component = '/index/index'
          }
          delete form.index
          await addMenuApi({ ...form })
          ElMessage.success('添加成功')
        } else {
          const edittype = props.editData.meta?.type ?? props.editData.type
          if (edittype == 1) {
            delete form.component
            delete form.pid
            delete form.name
            delete form.type
            delete form.is_menu
          } else if (edittype == 2) {
            form.pid = props.editData.p_id
            form.permission = form.name
            delete form.pid
            delete form.name
            delete form.type
            delete form.is_menu
          } else {
            form.permission = form.name
            delete form.name
            delete form.pid
            delete form.type
            delete form.status
            delete form.is_menu
            delete form.component
            delete form.icon
            delete form.path
          }
          form.id = props.editData.id
          await editMenuApi({ ...form })
          ElMessage.success('编辑成功')
        }
        emit('submit', { ...form })
        handleCancel()
      }
    })
  }

  /**
   * 取消操作
   */
  const handleCancel = (): void => {
    emit('update:visible', false)
  }

  /**
   * 对话框关闭后的回调
   */
  const handleClosed = (): void => {
    resetForm()
    isEdit.value = false
  }

  /**
   * 监听对话框显示状态
   */
  watch(
    () => props.visible,
    (newVal) => {
      if (newVal) {
        menuType.value = props.type
        nextTick(() => {
          if (props.editData) {
            loadFormData()
          }
        })
      }
    }
  )

  /**
   * 监听菜单类型变化
   */
  watch(
    () => props.type,
    (newType) => {
      if (props.visible) {
        menuType.value = newType
      }
    }
  )
</script>
